上面的博文介绍的都是源码src下的zepto.js文件,接着我们来看看zepto的事件模块,对应文件是event.js
代码挂在我的github上,对应文件夹v0.3.2(只实现on),v0.3.3(完整实现)。
https://github.com/zrysmt/DIY-zepto
1.绑定事件
实例Demo1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<div id="foo1">foo1</div>
<div id="foo2">foo2</div>
<div id="foo3">foo3
<div id="foo31">foo31</div>
</div>
<a href="demo1.html" class="my-a">demo1.html</a>
<script src="zepto.js"></script>
<script type="text/javascript">
var div1 = $('#foo1');
var div2 = $('#foo2');
$('body').on('click', '#foo1', function(event) {
console.log(event);
event.preventDefault();
alert("点击");
});
$('body').on('click', '#foo2', 'test',function(event) {
event.preventDefault();
alert("点击foo2"+event.data);//点击foo2test
});
$('#foo3').on('click', function(event) {
alert("点击");
});
$('body').on('click', '.my-a', false);//不跳转
</script>
1.1 handlers
对象
handlers
对象的数据格式如下:
1 | { |
1.2 全局变量
1 | var _zid = 1, //用来生成标示元素和回调函数的id,每标示一个就+1 |
1.3 添加三个方法:isDefaultPrevented、isDefaultPrevented和isPropagationStopped
- 如果
preventDefault()
被该事件的实例调用,那么返回true。 这可作为跨平台的替代原生的defaultPrevented
属性,如果defaultPrevented
缺失或在某些浏览器下不可靠的时候 - 如果
stopImmediatePropagation()
被该事件的实例调用,那么返回true。Zepto在不支持该原生方法的浏览器中实现它(例如老版本的Android) - 如果
stopPropagation()
被该事件的实例调用,那么返回true
通过改写原生的preventDefault、stopImmediatePropagation和stopPropagation方法实现新增三个方法
新增的三个方法:
1 | var returnTrue = function() { |
1.4 $.fn.on
实现
1 | /**调用形式: |
1.5 核心函数add remove
1 | /** |
1.6 工具函数
1.6.1 zid
函数
1 | //通过一个_zid而不是通过DOM对象的引用来连接handler是因为:防止移除掉DOM元素后, |
1.6.2 focus和blur事件的冒泡问题
1 | //focus和blur事件本身是不冒泡的,如果需要对这两个事件进行事件代理,就要运用一些小技巧。 |
1.6.3 实际传入到addEventListener第二个参数
1 | // 构建事件代理中的事件对象 |
1.6.4 其余工具函数
1 | // 根据给定的参数在handlers变量中寻找对应的handler |
2.取消事件绑定
示例:1
$('body').off('click', '#foo1');
1 | $.fn.off = function(event, selector, callback) { |
3.触发事件
$.Event
:创建并初始化一个指定的DOM事件。如果给定properties对象,使用它来扩展出新的事件对象。默认情况下,事件被设置为冒泡方式;这个可以通过设置bubbles
为false
来关闭。
通过document.createEvent创建事件对象,然后通过dispatchEvent(源码中在$.fn.trigger
和$.fn.triggerHandler
中处理)来出发。
1 | // Create the event. |
上面有点要注意的就是当创建鼠标相关的事件时要在document.createEvent
的第一个参数中传入MouseEvents
,以提供更多的事件属性。鼠标相关的事件指的是:click、mousedown、mouseup和mousemove
示例:1
2
3
4$(document).on('mylib:change', function(e, from, to) {
console.log('change on %o with data %s, %s', e.target, from, to)
})
$(document.body).trigger('mylib:change', ['one', 'two'])
源码实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44$.fn.trigger = function(event, args) {
event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event);
event._args = args;
return this.each(function() {
// handle focus(), blur() by calling them directly
// 过直接调用focus()和blur()方法来触发对应事件,这算是对触发事件方法的一个优化
if (event.type in focus && typeof this[event.type] == "function") {
this[event.type]();
}
// items in the collection might not be DOM elements
else if ('dispatchEvent' in this) {
this.dispatchEvent(event);
} else {
$(this).triggerHandler(event, args);
}
});
};
// triggers event handlers on current element just as if an event occurred,
// doesn't trigger an actual event, doesn't bubble
// 直接触发事件的回调函数,而不是直接触发一个事件,所以也不冒泡
$.fn.triggerHandler = function(event, args) {
var e, result;
this.each(function(i, element) {
e = createProxy(isString(event) ? $.Event(event) : event);
e._args = args;
e.target = element;
$.each(findHandlers(element, event.type || event), function(i, handler) {
result = handler.proxy(e);
if (e.isImmediatePropagationStopped()) return false;
});
});
return result;
};
//生成一个模拟事件,如果是鼠标相关事件,document.createEvent传入的第一个参数为'MouseEvents'
$.Event = function(type, props) {
if (!isString(type)) props = type, type = props.type;
var event = document.createEvent(specialEvents[type] || 'Events'),
bubbles = true
if (props)
for (var name in props)(name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]);
event.initEvent(type, bubbles, true);
return compatible(event);
};
4.bind,unbind,one实现
1 | $.fn.bind = function(event, data, callback) { |
还有省略一部分,全部代码挂在我的github上,对应文件夹v0.3.2(只实现on),v0.3.3(完整实现)。
https://github.com/zrysmt/DIY-zepto
参考阅读: